import LXCOM from '../common/common.js'
import UtilFuncs from '../common/tools/utilfuncs.js'
var funcs = UtilFuncs.UtilFuncs;

import globalConst from '../common/globalConst.js';
var global = globalConst.GlobalConst;

import coord from '../common/struct/coord.js';
import {LGXEnums}  from '../common/sysenum.js';

import { PositionUtil } from '../common/tools/positionutil.js';
import fillCommStru from '../common/fillCommStru.js';


class PathUnit {
    constructor() {
        //对应enums.HatchBoundaryType
        this.type = "line";//"line" "arc" "spline" "lwpolyline" "ellipsearc"
        this.coordDecs = "";//坐标描述
        this.nextUnit = null;
        this.independentRegion = false;//本身就是封闭图形，如矩形、封闭多边形、圆形、封闭曲线
    }

    clone(src){
        this.type = src.type;
        this.independentRegion = src.independentRegion;
        this.coordDecs = PositionUtil.cloneSrcPos(src.coordDecs);
        if (src.nextUnit){
            this.nextUnit = new PathUnit();
            this.nextUnit.clone(src.nextUnit);
        }
    }

    rotate(rotCntPt, rotRad) {
        let angle = PositionUtil.rotatePos(this.coordDecs, rotCntPt, rotRad);
        if (this.nextUnit){
            this.nextUnit.rotate(rotCntPt, rotRad);
        }
    }

    offset(tx, ty) {
        this.coordDecs.offset(tx,ty);
        if (this.nextUnit){
            this.nextUnit.offset(tx, ty);
        }
    }

    mirror(stPt, nextPt) {
        this.coordDecs.mirror(stPt, nextPt);
        if (this.nextUnit){
            this.nextUnit.mirror(stPt, nextPt);
        }
    }

    scale(basePt,sx,sy){
        this.coordDecs.scale(basePt,sx,sy);
        if (this.nextUnit){
            this.nextUnit.scale(basePt,sx,sy);
        }
    }

    getMainFeaturePTLst(tFeaturePTLst,transformInfo) {
        this.coordDecs.getFeaturePt(tFeaturePTLst,transformInfo);
        if (this.nextUnit){
            this.nextUnit.getMainFeaturePTLst(tFeaturePTLst,transformInfo);
        }
    }
}

class PathUnitLink {
    constructor() {
        this.m_pathStartUnit = null;
        this.m_pathEndUnit = null;
    }
    getPathStartUnit(){
        return this.m_pathStartUnit;
    }

    setPathStartUnit(unit){
        this.m_pathStartUnit = unit;
    }

    calScope(mapscale) {
        let rect = new LXCOM.LGXRect();
        let stUnit = this.m_pathStartUnit;
        this.calScopePathUnit(true, stUnit, rect);
        return rect;
    }

    calScopePathUnit(initflag, pathUnit, rect) {
        if (pathUnit.type == "line" 
        || pathUnit.type == "bezier") {
            let linePtList = pathUnit.coordDecs.posList;
            this.calSubUnitScopeByPTList(linePtList, initflag, rect);
        }
        else if (pathUnit.type == "arc") {
            let arcPosition = pathUnit.coordDecs;
            this.calArcUnitScope(arcPosition, initflag,rect);
        }

        let nextUnit = pathUnit.nextUnit;
        if (nextUnit) {
            this.calScopePathUnit(false, nextUnit, rect);
        }
    }

    calArcUnitScope(postion,initflag,rect) {
        //先获取圆弧端点、中间点
        let arcPTInfo = funcs.getArcControlPoint(postion);

        let list = [];
        list.push(arcPTInfo.stPoint);
        list.push(arcPTInfo.endPoint);
        list.push(arcPTInfo.midPoint);

        //四个特征点是否在圆弧上
        let x = postion.x + postion.radius;
        let y = postion.y;
        let tmpPt = { x, y };
        if (funcs.chkPtInArcSec(postion, tmpPt)) {
            list.push(tmpPt);
        }

        x = postion.x - postion.radius;
        y = postion.y;
        tmpPt = { x, y };
        if (funcs.chkPtInArcSec(postion, tmpPt)) {
            list.push(tmpPt);
        }

        x = postion.x;
        y = postion.y + postion.radius;
        tmpPt = { x, y };
        if (funcs.chkPtInArcSec(postion, tmpPt)) {
            list.push(tmpPt);
        }

        x = postion.x;
        y = postion.y - postion.radius;
        tmpPt = { x, y };
        if (funcs.chkPtInArcSec(postion, tmpPt)) {
            list.push(tmpPt);
        }
        this.calSubUnitScopeByPTList(list, initflag, rect);
    }

    calSubUnitScopeByPTList(PtList, initflag, rect) {
        if (initflag) {
            let pt = PtList[0];
            rect.left = pt.x;
            rect.right = pt.x;
            rect.bottom = pt.y;
            rect.top = pt.y;
            for (let i = 1; i < PtList.length; i++) {
                pt = PtList[i];
                this.compareScopeWithPt(rect, pt);
            }
        }
        else {
            for (let i = 0; i < PtList.length; i++) {
                let pt = PtList[i];
                this.compareScopeWithPt(rect, pt);
            }
        }
    }

    compareScopeWithPt(rect, pt) {
        rect.left = Math.min(rect.left, pt.x);
        rect.right = Math.max(rect.right, pt.x);
        rect.bottom = Math.min(rect.bottom, pt.y);
        rect.top = Math.max(rect.top, pt.y);
    }

    clone(srcLink){
        let srcStUnit = srcLink.m_pathStartUnit;
        let dstStUnit = new PathUnit;
        dstStUnit.clone(srcStUnit);
        this.setPathStartUnit(dstStUnit);
    }

    rotate(rotCntPt, rotRad) {
        let stUnit = this.m_pathStartUnit;
        stUnit.rotate(rotCntPt, rotRad);
        return ;
    }

    offset(tx, ty) {
        let stUnit = this.m_pathStartUnit;
        stUnit.offset(tx, ty);
        return ;
    }

    mirror(stPt, nextPt) {
        let stUnit = this.m_pathStartUnit;
        stUnit.mirror(stPt, nextPt);
        return ;
    }

    scale(basePt,sx,sy){
        let stUnit = this.m_pathStartUnit;
        stUnit.scale(basePt,sx,sy);
        return ;
    }

    getRelatePathUnit(preUnit,tAllPathUnitArr){
        let nextUnit = null;
        if (!preUnit){
            tAllPathUnitArr.push(this.m_pathStartUnit);
            nextUnit = this.m_pathStartUnit.nextUnit;
        }
        else{
            if (tAllPathUnitArr.indexOf(preUnit) == -1){
                tAllPathUnitArr.push(preUnit);
            }
            nextUnit = preUnit.nextUnit;
        }
        if (nextUnit){
            this.getRelatePathUnit(nextUnit,tAllPathUnitArr);
        }
    }

        //符号“$”隔开多个环，第一个环为外环；
    //符号“@”隔开环内的子图元
    //各子图元根据不同的类型有不同的描述方式
    //"line,x1,y1;x2,y2;....@arc,cntx,cnty,radius,stangle,endangle,anticlockwise@bezier,st,ctrlPt1,
    //ctrlPt2,end@quadratic,st,end,ctrlPt$line,x1,y1;x2,y2;....@arc,cntx,cnty,radius,stangle,endangle,anticlockwise" 
    parseFrmCoordDesc(linkDesc){
        let list = linkDesc.split("@");
    }

    getMainFeaturePTLst(tFeaturePTLst,transformInfo) {
        let stUnit = this.m_pathStartUnit;
        if (stUnit){
            stUnit.getMainFeaturePTLst(tFeaturePTLst,transformInfo);
        }
    }
}

class PathCoordPos extends coord.AbstractPos{
    constructor(){
        super();
        this.pathLinkList = [];
        this.posType = LGXEnums.LGXPosMode.pathLinke_mode;
    }

    clone(srcPathCoordPos){
        this.pathLinkList = [];
        for (let i = 0;i < srcPathCoordPos.pathLinkList.length;i++){
            let t = srcPathCoordPos.pathLinkList[i];
            let newLink = new PathUnitLink();
            newLink.clone(t);
            this.pathLinkList.push(newLink);
        }
    }

    rotate(rotCntPt, rotRad){
        for (let i = 0;i < this.pathLinkList.length;i++){
            let t = this.pathLinkList[i];
            t.rotate(rotCntPt, rotRad);
        }
    }
    offset(tx,ty){
        for (let i = 0;i < this.pathLinkList.length;i++){
            let t = this.pathLinkList[i];
            t.offset(tx,ty);
        }
    }

    mirror(stPt, nextPt) {
        for (let i = 0;i < this.pathLinkList.length;i++){
            let t = this.pathLinkList[i];
            t.mirror(stPt, nextPt);
        }
        return 0;
    }

    mirrorCopy(stPt, nextPt){
        let pos = new PathCoordPos();
        pos.clone(this);
        pos.mirror(stPt,nextPt);
        return pos;
    }

    createCopyPos(offset) {
        let pos = new PathCoordPos();
        pos.clone(this);
        pos.offset(offset.x,offset.y);
        return pos;
    }

    //符号“$”隔开多个环，第一个环为外环；
    //符号“@”隔开环内的子图元
    //各子图元根据不同的类型有不同的描述方式
    //"line,x1,y1;x2,y2;....@arc,cntx,cnty,radius,stangle,endangle,anticlockwise@bezier,st,ctrlPt1,
    //ctrlPt2,end@quadratic,st,end,ctrlPt$line,x1,y1;x2,y2;....@arc,cntx,cnty,radius,stangle,endangle,anticlockwise"    
    toString() {
        let outPathLink = this.pathLinkList[0];
        let stUnit = outPathLink.getPathStartUnit();
        let outParam = { coordDesc: '' };
        this.getPathUnitDesc(stUnit, outParam);
        let totalCoordDesc = outParam.coordDesc;
        for (let i = 1; i < this.pathLinkList.length; i++) {
            let innerPathLink = this.pathLinkList[i];
            let innerStUnit = innerPathLink.getPathStartUnit();
            let innerLinkParam = { coordDesc: '' };
            this.getPathUnitDesc(innerStUnit, innerLinkParam);
            totalCoordDesc = totalCoordDesc + global.LINKMARK + innerLinkParam.coordDesc;
        }
        return totalCoordDesc;
    }

    getPathUnitDesc(pathUnit, outParam) {
        let subDesc = "";
        if (pathUnit.type == fillCommStru.PathUnitType.line) {
            subDesc = "@line,"
            subDesc = subDesc + pathUnit.coordDecs.toString();
        }
        else if (pathUnit.type == fillCommStru.PathUnitType.arc) {
            subDesc = "@arc,";
            subDesc = subDesc + pathUnit.coordDecs.toString();
        }
        else if (pathUnit.type == fillCommStru.PathUnitType.bezier) {
            subDesc = "@bezier,";
            subDesc = subDesc + pathUnit.coordDecs.toString();
        }
        else if (pathUnit.type == fillCommStru.PathUnitType.spline) {
            subDesc = "@spline,";
            subDesc = subDesc + pathUnit.coordDecs.toString();
        }
        else if (pathUnit.type == fillCommStru.PathUnitType.ellipseArc) {
            subDesc = "@ellipseArc,";
            subDesc = subDesc + pathUnit.coordDecs.toString();
        }
        outParam.coordDesc = outParam.coordDesc + subDesc;
        let nextUnit = pathUnit.nextUnit;
        if (nextUnit) {
            this.getPathUnitDesc(nextUnit, outParam);
        }
    }

    scale(basePt,sx,sy){
        for (let i = 0;i < this.pathLinkList.length;i++){
            let t = this.pathLinkList[i];
            t.scale(basePt,sx,sy);
        }
    }

}

export default {PathUnitLink, PathUnit,PathCoordPos }
